package com.dongdongshop.service.impl;


import cn.hutool.json.JSONObject;
import com.dongdongshop.mapper.TbSeckillGoodsMapper;
import com.dongdongshop.mapper.TbSeckillOrderMapper;
import com.dongdongshop.pojo.TbSeckillGoods;
import com.dongdongshop.pojo.TbSeckillGoodsExample;
import com.dongdongshop.pojo.TbUser;
import com.dongdongshop.service.SeckillService;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@DubboService
@Service
public class SeckillServiceImpl implements SeckillService {
    @Autowired
    private TbSeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private TbSeckillOrderMapper seckillOrderMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public void prepareHot() {
        TbSeckillGoodsExample example = new TbSeckillGoodsExample();
        TbSeckillGoodsExample.Criteria criteria = example.createCriteria();
//        条件
//        1.当前时间在 开始时间和结束时间之间
//        2.库存数量大于0
//        3.状态为 1  已审核

        Date date = new Date();
        criteria.andStartTimeLessThanOrEqualTo(date);
        criteria.andEndTimeGreaterThanOrEqualTo(date);
        criteria.andStatusEqualTo("1");
        criteria.andStockCountGreaterThanOrEqualTo(0);


        List<TbSeckillGoods> tbSeckillGoods = seckillGoodsMapper.selectByExample(example);
        for (TbSeckillGoods tbSeckillGood : tbSeckillGoods) {
            redisTemplate.boundHashOps("seckills").put(tbSeckillGood.getId(),tbSeckillGood);
            //将库存存入redis,方便使用库存自减
            stringRedisTemplate.opsForValue().set(String.valueOf(tbSeckillGood.getId()),String.valueOf(tbSeckillGood.getStockCount()));
        }
    }

    @Override
    public List<TbSeckillGoods> listSeckill() {
        List seckills = redisTemplate.boundHashOps("seckills").values();
        return seckills;
    }

    @Override
    public TbSeckillGoods selectSeckillById(Long id) {
        return (TbSeckillGoods)redisTemplate.boundHashOps("seckills").get(id);
    }

    @Override
    public void createOrder(Long goodsId, TbUser user) throws Exception {
//先根据id从缓存中取出库存数量
        String s = stringRedisTemplate.opsForValue().get(String.valueOf(goodsId));

        // 判断库存是否充足
        if (Long.parseLong(s) == 0){
            throw new Exception("库存不足");
        }
        //减库存,并返回减完之后的数值
        Long stockCount = stringRedisTemplate.opsForValue().decrement(String.valueOf(goodsId));


        //更新 redis
        TbSeckillGoods goods = selectSeckillById(goodsId);
        goods.setStockCount(stockCount.intValue());
        redisTemplate.boundHashOps("seckills").put(goodsId,goods);
        //如果卖完最后一个
        if (stockCount.longValue() == 0){
            //更新库存
            seckillGoodsMapper.updateByPrimaryKeySelective(goods);
        }

        //异步下单,削峰填谷,解决并发问题
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOpt("userName",user.getUsername());
        jsonObject.putOpt("goodsId",goodsId);

        rocketMQTemplate.convertAndSend("create-order-seckill",jsonObject.toString());
    }
}
